package com.gsafety.wellsfort.common.util;


import com.alibaba.fastjson.JSON;
import com.gsafety.wellsfort.annotation.ExcelField;
import com.gsafety.wellsfort.annotation.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户excel工具类 excel格式要按照规范严格去控制
 *
 * @author tangjiawei
 */
@Slf4j
public class ExcelUtil {

    public static <T> List<T> getDtoList(File file, Class<T> cls) throws Exception {
        try {
            List<T> list = new ArrayList<T>();
            List<Field> fields = getAnnotationFields(cls);
            try {
                // 1、获取文件输入流
                InputStream inputStream = new FileInputStream(file);
                // 2、获取Excel工作簿对象
                HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
                // 3、得到Excel工作表对象
                HSSFSheet sheetAt = workbook.getSheetAt(0);

                // 4、循环读取表格数据
                for (Row row : sheetAt) {
                    T object = cls.newInstance();
                    // 首行（即表头）不读取
                    if (row.getRowNum() == 0) {
                        continue;
                    }
                    // 读取当前行中单元格数据，索引从0开始
                    for (int i = 0; i < fields.size(); i++) {
                        Field field = fields.get(i);
                        if (row.getCell(i) == null) {
                            //判断是否是必填选项
                            NotNull notNull = field.getAnnotation(NotNull.class);
                            if (notNull != null) {
                                throw new Exception(notNull.desc() + "不能为空!");
                            }
                            continue;
                        }
                        if (field.getType() == Date.class) {
                            // 日期格式特殊处理
                            Date date = getFormatDate(row.getCell(i));
                            field.set(object, date);
                        } else {
                            row.getCell(i).setCellType(CellType.STRING);
                            if (field.getType() == Integer.class) {
                                field.set(object, Integer.parseInt(row.getCell(i).getStringCellValue()));
                            } else if (field.getType() == Byte.class) {
                                field.set(object, Byte.parseByte(row.getCell(i).getStringCellValue()));
                            } else if (field.getType() == Long.class) {
                                field.set(object, Long.parseLong(row.getCell(i).getStringCellValue()));
                            } else if (field.getType() == Double.class) {
                                field.set(object, Double.parseDouble(row.getCell(i).getStringCellValue()));
                            } else if (field.getType() == String.class) {
                                field.set(object, row.getCell(i).getStringCellValue());
                            }
                        }
                    }
                    list.add(object);
                }
                // 5、关闭流
                workbook.close();
            } catch (IOException e) {
                log.error("exception={}", e);
            }
            return list;
        } catch (Exception e) {
            log.error("exception={}", e);
            throw e;
        }
    }

    /**
     * 获取注解属性集合
     *
     * @param cls
     * @param <T>
     * @return
     */
    private static <T> List<Field> getAnnotationFields(Class<T> cls) {
        List<Field> list = new ArrayList<>();
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            ExcelField excelField = field.getAnnotation(ExcelField.class);
            if (excelField != null) {
                field.setAccessible(true);
                list.add(field);
            }
        }
        return list;
    }

    private static Date getFormatDate(Cell cell) {
        return cell.getDateCellValue();
    }
}
